﻿using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using CommunityToolkit.Mvvm.Input;
using System.IO;
using System.Windows;

using Microsoft.Win32;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Collections.ObjectModel;
using OfficeOpenXml;
using System.Windows.Input;
using System.IO.Packaging;


namespace MapMergeTool
{
    public partial class MergeViewModel: ObservableRecipient
    {

        [ObservableProperty]
        private string  sourcePath1  = "";
        [ObservableProperty]
        private string  sourcePath2 = "";
        [ObservableProperty]
        private string targetSavePath = "";
        [ObservableProperty]
        private string targetPatternFile = "";
        [ObservableProperty]
        private List<string> ?patternFiles;
        [ObservableProperty]
        private static  string _patternsFilePath =  Path.Combine(  AppDomain.CurrentDomain.BaseDirectory, "Pattern");

      

        [ObservableProperty]
        private List<string>? source1Files;

        [ObservableProperty]
        private List<string>? source2Files;

        [ObservableProperty]
        private bool isWriteTxt  = true;

        private List<DataPath> dataPaths;

        private List<DataPath> txtdataPaths;
        [ObservableProperty]
        private List<string>? txtsource1Files;

        [ObservableProperty]
        private List<string>? txtsource2Files;

        public MergeViewModel()
        {
            PatternFiles= GetAllExcelFiles(PatternsFilePath,false);
        }

        [RelayCommand]
        private void SelectSourcePath1()
        {
            var dialog = new OpenFileDialog();
            dialog.CheckFileExists = false;
            dialog.ValidateNames = false;
            dialog.FileName = "文件夹选择";
            dialog.Filter = "文件夹|*";

            if (dialog.ShowDialog() == true)
            {
                SourcePath1 = System.IO.Path.GetDirectoryName(dialog.FileName);            
            }
        }

        [RelayCommand]
        private void SelectSourcePath2()
        {
            var dialog = new OpenFileDialog();
            dialog.CheckFileExists = false;
            dialog.ValidateNames = false;
            dialog.FileName = "文件夹选择";
            dialog.Filter = "文件夹|*";

            if (dialog.ShowDialog() == true)
            {
                SourcePath2 = System.IO.Path.GetDirectoryName(dialog.FileName);
            }
        }

        [RelayCommand]
        private void SelectTargetSavePath()
        {
            var dialog = new OpenFileDialog();
            dialog.CheckFileExists = false;
            dialog.ValidateNames = false;
            dialog.FileName = "文件夹选择";
            dialog.Filter = "文件夹|*";

            if (dialog.ShowDialog() == true)
            {
                TargetSavePath = System.IO.Path.GetDirectoryName(dialog.FileName);
            }
        }

        [RelayCommand]
        private void OpenPatternFilePath()
        {
            try
            {
                if (string.IsNullOrEmpty(PatternsFilePath))
                {
                    MessageBox.Show("文件夹路径不能为空", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                // 自动创建不存在的文件夹（包括所有父目录）
                System.IO.Directory.CreateDirectory(PatternsFilePath);

                // 打开文件夹
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                {
                    FileName = PatternsFilePath,
                    UseShellExecute = true
                });

            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作出错：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }


        }

        public List<string> GetAllExcelFiles(string folderPath, bool includeSubfolders = false)
        {
            List<string> excelFiles = new List<string>();

            try
            {
                // 验证文件夹是否存在
                if (!Directory.Exists(folderPath))
                {
                    Console.WriteLine($"错误：文件夹 '{folderPath}' 不存在。");
                    return excelFiles;
                }

                // 获取所有XLSX文件（包括.xlsx和.xls格式）
                SearchOption searchOption = includeSubfolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

                // 使用LINQ查询获取所有XLSX文件（不区分大小写）
                excelFiles = Directory.GetFiles(folderPath, "*.*", searchOption)
                    .Where(file => file.ToLower().EndsWith(".xlsx") || file.ToLower().EndsWith(".xls"))
                    .ToList();

                Console.WriteLine($"找到 {excelFiles.Count} 个Excel文件。");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取文件时出错：{ex.Message}");
            }

            return excelFiles;
        }

        public List<string> GetAllTxtFiles(string folderPath, bool includeSubfolders = false)
        {
            List<string> txtFiles = new List<string>();

            try
            {
                // 验证文件夹是否存在
                if (!Directory.Exists(folderPath))
                {
                    Console.WriteLine($"错误：文件夹 '{folderPath}' 不存在。");
                    return txtFiles;
                }

                // 设置搜索选项（是否包含子文件夹）
                SearchOption searchOption = includeSubfolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

                // 获取所有TXT文件（不区分大小写）
                txtFiles = Directory.GetFiles(folderPath, "*.*", searchOption)
                    .Where(file => file.ToLower().EndsWith(".txt"))
                    .ToList();

                Console.WriteLine($"找到 {txtFiles.Count} 个TXT文件。");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取文件时出错：{ex.Message}");
            }

            return txtFiles;
        }


        [RelayCommand]
        private void StartMerge()
        {
            dataPaths = new List<DataPath>();
            Source1Files = GetAllExcelFiles(SourcePath1);
            Source2Files = GetAllExcelFiles(SourcePath2);


            txtdataPaths = new List<DataPath>();
            Txtsource1Files = GetAllTxtFiles(SourcePath1);
            Txtsource2Files = GetAllTxtFiles(SourcePath2);

            // 预处理Source2Files，建立ID到文件路径的映射
            var idToFiles = new Dictionary<string, List<string>>();
            foreach (var file2 in Source2Files)
            {
                string[] parts = file2.Split('-');
                if (parts.Length >= 2)
                {
                    string id = parts.Last();
                    if (!idToFiles.ContainsKey(id))
                        idToFiles[id] = new List<string>();

                    idToFiles[id].Add(file2);
                }
            }

            // 单次循环处理Source1Files
            foreach (var file1 in Source1Files)
            {
                string[] parts1 = file1.Split('-');
                if (parts1.Length < 2) continue; // 确保有足够的分隔符

                string id1 = parts1.Last();
                string stationId1 = parts1[parts1.Length - 2];
                string key1 = stationId1.Substring(Math.Max(0, stationId1.Length - 2));

                // 快速查找匹配的文件
                if (idToFiles.TryGetValue(id1, out var matchedFiles))
                {
                    foreach (var file2 in matchedFiles)
                    {
                        string[] parts2 = file2.Split('-');
                        string stationId2 = parts2[parts2.Length - 2];
                        string key2 = stationId2.Substring(Math.Max(0, stationId2.Length - 2));

                        DataPath dataPath = new DataPath();
                        dataPath.SourcePath1 = file1;
                        dataPath.SourcePath2 = file2;
                        dataPath.Key1 = key1;
                        dataPath.Key2 = key2;
                        dataPath.PatternFile = TargetPatternFile;
                        dataPath.TargetSaveFile = Path.Combine(TargetSavePath, KeepOnlyMatchingChars(file1, file2));
                        dataPaths.Add(dataPath);
                    }
                }
            }


            // 处理TXT文件：建立ID到文件路径的映射（与Excel逻辑一致）
            var txtIdToFiles = new Dictionary<string, List<string>>();
            foreach (var txtFile2 in Txtsource2Files)
            {
                string[] parts = txtFile2.Split('-');
                if (parts.Length >= 2)
                {
                    string id = parts.Last(); // 取分割后最后一段作为ID
                    if (!txtIdToFiles.ContainsKey(id))
                        txtIdToFiles[id] = new List<string>();

                    txtIdToFiles[id].Add(txtFile2);
                }
            }

            // 循环处理Txtsource1Files，匹配对应的Txtsource2Files
            foreach (var txtFile1 in Txtsource1Files)
            {
                string[] parts1 = txtFile1.Split('-');
                if (parts1.Length < 2) continue; // 跳过格式不符合的文件

                string id1 = parts1.Last(); // 提取ID用于匹配
                string stationId1 = parts1[parts1.Length - 2]; // 取倒数第二段作为stationId
                string key1 = stationId1.Substring(Math.Max(0, stationId1.Length - 2)); // 取stationId后两位作为key

                // 查找同ID的TXT文件
                if (txtIdToFiles.TryGetValue(id1, out var matchedTxtFiles))
                {
                    foreach (var txtFile2 in matchedTxtFiles)
                    {
                        string[] parts2 = txtFile2.Split('-');
                        string stationId2 = parts2[parts2.Length - 2];
                        string key2 = stationId2.Substring(Math.Max(0, stationId2.Length - 2));

                        // 构建TXT文件的数据路径映射
                        DataPath txtDataPath = new DataPath();
                        txtDataPath.SourcePath1 = txtFile1; // TXT源路径1
                        txtDataPath.SourcePath2 = txtFile2; // TXT源路径2
                        txtDataPath.Key1 = key1; // TXT的key1（与Excel逻辑一致）
                        txtDataPath.Key2 = key2; // TXT的key2
                        //txtDataPath.PatternFile = TargetPatternFile; // 复用目标模板文件
                        txtDataPath.TargetSaveFile = Path.Combine(TargetSavePath, KeepOnlyMatchingChars(txtFile1, txtFile2)); // 生成目标保存路径
                        txtdataPaths.Add(txtDataPath);
                    }
                }
            }





            if (CopySheetEntirely(dataPaths,txtdataPaths))
            {
                MessageBox.Show("完成！");
            }
            else
            {
                MessageBox.Show("失败！");
            }
        }

        public static string KeepOnlyMatchingChars(string str1, string str2)
        {
            if (str1.Length != str2.Length)
                return "";
            str1= Path.GetFileName(str1);
            str2 = Path.GetFileName(str2);
            var result = new System.Text.StringBuilder(str1.Length);
            for (int i = 0; i < str1.Length; i++)
            {
                if (str1[i] == str2[i])
                {
                    result.Append(str1[i]); // 只添加匹配的字符
                }
            }
            return result.ToString();
        }

        private bool CopySheetEntirely(List<DataPath> dataPaths,  List<DataPath> txtdataPaths=null)
        {
            foreach (var dataPath in dataPaths)
            {

                if (!File.Exists(dataPath.SourcePath1))
                    return false;

                // 复制模板文件
                File.Copy(TargetPatternFile, dataPath.TargetSaveFile, true);
                ExcelPackage.License.SetNonCommercialPersonal("My Name");

                // 优化点：只打开一次目标文件，完成所有操作后再保存
                using (var targetPackage = new ExcelPackage(new FileInfo(dataPath.TargetSaveFile)))
                {
                    // 处理第一个源文件
                    using (var sourcePackage1 = new ExcelPackage(new FileInfo(dataPath.SourcePath1)))
                    {
                        var sourceSheet1 = sourcePackage1.Workbook.Worksheets["Map"];
                        if (sourceSheet1 == null)
                            throw new Exception("源文件1中没有Map工作表");

                        // 删除已存在的工作表并添加新的
                        if (targetPackage.Workbook.Worksheets[dataPath.Key1] != null)
                            targetPackage.Workbook.Worksheets.Delete(dataPath.Key1);

                        targetPackage.Workbook.Worksheets.Add(dataPath.Key1, sourceSheet1);
                    }

                    // 处理第二个源文件
                    using (var sourcePackage2 = new ExcelPackage(new FileInfo(dataPath.SourcePath2)))
                    {
                        var sourceSheet2 = sourcePackage2.Workbook.Worksheets["Map"];
                        if (sourceSheet2 == null)
                            throw new Exception("源文件2中没有Map工作表");

                        // 删除已存在的工作表并添加新的
                        if (targetPackage.Workbook.Worksheets[dataPath.Key2] != null)
                            targetPackage.Workbook.Worksheets.Delete(dataPath.Key2);

                        targetPackage.Workbook.Worksheets.Add(dataPath.Key2, sourceSheet2);
                    }

                    // 处理"合并"工作表
                    if (targetPackage.Workbook.Worksheets["合并"] == null)
                    {
                        return false;
                    }
                    var sourceSheet = targetPackage.Workbook.Worksheets["合并"];
                    var newSheet = targetPackage.Workbook.Worksheets.Add("Sheet1", sourceSheet);

        
                    targetPackage.Workbook.Worksheets.Delete("合并");

                    // 隐藏指定工作表
                    targetPackage.Workbook.Worksheets[dataPath.Key1].Hidden = eWorkSheetHidden.Hidden;
                    targetPackage.Workbook.Worksheets[dataPath.Key2].Hidden = eWorkSheetHidden.Hidden;

                    // 关键步骤1：强制计算所有公式（包括隐藏的工作表）
                    targetPackage.Workbook.Calculate();

                    targetPackage.Save();


                    //****************导出 TXT部分**********************************************************

                    if (IsWriteTxt)
                    {
                        string path = PatternsFilePath + "\\字符转换表.csv";
                        if (!File.Exists(path))
                        {
                            MessageBox.Show("不存在："+path);
                            return false;
                        }

                        // 读取所有行
                        string[] allLines = File.ReadAllLines(path, Encoding. GetEncoding("GB2312"));
                        Dictionary<string ,string>rules = new Dictionary<string ,string>();

                        for (int i = 1; i < allLines.Length; i++)
                        {
                            rules.Add(allLines[i].Split(',')[0], allLines[i].Split(',')[1]);
                        }


                        // 使用已打开的targetPackage，避免重复打开文件
                        var txtsheet = targetPackage.Workbook.Worksheets["Sheet1"];
                        int columnCount = txtsheet.Dimension.End.Column;
                        int rowCount = txtsheet.Dimension.End.Row;

                        TxtData txtData = new TxtData();


                        DataPath dp = txtdataPaths.First(p => p.TargetSaveFile.Split('-').Last().Split('.').First() == dataPath.TargetSaveFile.Split('-').Last().Split('.').First());

                        using (StreamReader reader = new StreamReader(dp.SourcePath1))
                        {
                            string line;
                            while ((line = reader.ReadLine()) != null)
                            {
                                if (line.Contains(":"))
                                {
                                    txtData.KeyValue.Add(line.Split(':').First() , line.Split(':').Last());                     
                                }
                            }
                        }

                        using (StreamReader reader = new StreamReader(dp.SourcePath2))
                        {
                            string line;
                            while ((line = reader.ReadLine()) != null)
                            {
                                if (line.Contains(":"))
                                {
                                    string key = line.Split(":").First();
                                    if (key.Contains("Bin") || key.Contains("BIN") || key.Contains("Total"))
                                    {
                                        int val = Convert.ToInt32(line.Split(":").Last());
                                        string valStr = "";
                                        txtData.KeyValue.TryGetValue(key, out valStr);
                                        int newVal = Convert.ToInt32(valStr) + val;
                                        txtData.KeyValue[key] = newVal.ToString();
                                    }
                                    if (key.Contains("LOT NO"))
                                    {
                                        string val = line.Split(":").Last();
                                        string valStr = "";
                                        txtData.KeyValue.TryGetValue(key, out valStr);
                                        string newVal = KeepOnlyMatchingChars(valStr, val);
                                        txtData.KeyValue[key] = newVal;
                                    }
                                }
                            }
                        }





                        // 读取数据
                        for (int r = 1; r <= rowCount; r++)
                        {                       
                            for (int c = 3; c <= columnCount; c++)
                            {
                                string data = txtsheet.Cells[r, c].Value?.ToString();
                                if (!string.IsNullOrEmpty(data))
                                {
                                    if (rules.ContainsKey(data))
                                    {
                                        data=rules[data];
                                    }
                                    txtData.MapDatas.Add(new MapData { X = c, Y = r, Val = data });
                                }
                            }
                        }

                        WriteCombinedData(txtData, dp.TargetSaveFile);
                    }



                }
            }

            return true;
        }





        [RelayCommand]
        private void  RefreshPatternFiles()
        {
            PatternFiles = GetAllExcelFiles(PatternsFilePath, false);
        }


        /// <summary>
        /// 先写入Key-Value对，再按Y分组写入MapData
        /// </summary>
        public void WriteCombinedData(TxtData txtData, string filePath)
        {
            // 检查数据有效性

            List<MapData> mapDataList= txtData.MapDatas;

            bool hasKeyValData = txtData != null && txtData.KeyValue.Any() ;
            bool hasMapData = mapDataList != null && mapDataList.Any();

   

            // 生成所有行数据
            var allLines = new List<string>();

            // 1. 添加Key-Value对
            foreach (var item in txtData!.KeyValue)
            {
                allLines.Add(item.Key+":"+item.Value);
            }




            // 添加空行分隔两种数据（可选）
            if (hasMapData)
                allLines.Add(string.Empty);
        

            // 2. 添加按Y分组的MapData
            if (hasMapData)
            {
                // 按Y分组并排序
                var groupedData = mapDataList
                    .GroupBy(data => data.Y)
                    .OrderBy(group => group.Key)
                    .Select(group => group
                        .OrderBy(data => data.X)
                        .Select(data => data.Val)
                        .ToList())
                    .ToList();

                // 将每组的Val用制表符连接成一行
                foreach (var vals in groupedData)
                {
                    allLines.Add(string.Join("", vals));
                }
            }

            // 3. 写入文件
            try
            {
                File.WriteAllLines(filePath, allLines);
                Console.WriteLine($"组合数据已写入：{filePath}");
            }
            catch (IOException ex)
            {
                Console.WriteLine($"写入失败：{ex.Message}");
            }
        }

    }

    public class DataPath
    {
        public string SourcePath1 { get; set; } = "";
        public string SourcePath2 { get; set; } = "";
        public string PatternFile { get; set; } = "";
        public string TargetSaveFile{ get; set; } = "";
        public string Key1 { get; set; } = "";
        public string Key2 { get; set; } = "";
    }


    public class TxtData
    {

        public TxtData()
        {
            //keys = new List<string>();
            //vals = new List<string>();
            KeyValue= new Dictionary<string ,string>();
            MapDatas=new List<MapData>();
        }

        public  Dictionary<string, string> KeyValue = new Dictionary<string, string>();
        //public List<string> keys { get; set; } = new List<string>();

        //public List<string> vals{ get; set; } =new List<string>();
        public List<MapData>MapDatas { get; set; }=new List<MapData>();
    }

    public class MapData
    {
        public int X { get; set; }
        public int Y { get; set; }
        public string Val { get; set; }
    }
}
